package cn.regexp.seckill.service.impl;


import cn.regexp.common.core.domain.Product;
import cn.regexp.common.core.domain.SeckillProduct;
import cn.regexp.common.core.domain.SeckillProductVo;
import cn.regexp.common.core.web.Result;
import cn.regexp.seckill.enums.SeckillRedisKeyEnum;
import cn.regexp.seckill.feign.ProductFeignApi;
import cn.regexp.seckill.mapper.SeckillProductMapper;
import cn.regexp.seckill.service.ISeckillProductService;
import com.alibaba.fastjson.JSON;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Regexpei
 * @date 2024/7/5 23:33
 * @description 秒杀商品服务实现类
 */
@Service
public class SeckillProductServiceImpl implements ISeckillProductService {
    @Autowired
    private SeckillProductMapper seckillProductMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ProductFeignApi productFeignApi;
    @Autowired
    private OrderInfoServiceImpl orderInfoSevice;

    @Override
    public List<SeckillProductVo> selectByType(int time) {
        // 查询秒杀商品
        List<SeckillProduct> seckillProductList = seckillProductMapper.queryCurrentlySeckillProduct(time);
        if (CollectionUtils.isEmpty(seckillProductList)) {
            return Collections.emptyList();
        }

        // 获取秒杀商品的 id
        List<Long> productIds = seckillProductList.parallelStream().map(SeckillProduct::getProductId)
                .collect(Collectors.toList());
        // 远程调用商品服务，获取商品信息
        Result<List<Product>> result = productFeignApi.queryProductByIds(productIds);
        if (result == null || result.hasError()) {
            return Collections.emptyList();
        }

        // 将商品信息聚合到 map 中
        Map<Long, Product> productGroupingById = Optional.ofNullable(result.getData()).orElse(Collections.emptyList())
                .stream().collect(Collectors.toMap(Product::getId, product -> product));

        List<SeckillProductVo> vos = new ArrayList<>();
        for (SeckillProduct seckillProduct : seckillProductList) {
            SeckillProductVo vo = new SeckillProductVo();
            Product product = productGroupingById.get(seckillProduct.getProductId());
            // 以下顺序不能调换，否则秒杀商品 ID 会被覆盖
            BeanUtils.copyProperties(product, vo);
            BeanUtils.copyProperties(seckillProduct, vo);
            vo.setCurrentCount(seckillProduct.getStockCount());
            vos.add(vo);
        }
        return vos;
    }

    @Override
    public List<SeckillProductVo> queryByTime(int time) {
        // 从 redis 中查询秒杀商品数据
        // 秒杀商品 json 字符串
        List<Object> jsonString = redisTemplate.opsForHash()
                .values(SeckillRedisKeyEnum.SECKILL_PRODUCT_LIST.getRealKey(time + ""));
        if (CollectionUtils.isEmpty(jsonString)) {
            return Collections.emptyList();
        }

        return jsonString.stream().map(item -> JSON.parseObject(item.toString(), SeckillProductVo.class))
                .collect(Collectors.toList());
    }

    @Override
    public SeckillProductVo find(int time, Long seckillId) {
        Object obj = redisTemplate.opsForHash()
                .get(SeckillRedisKeyEnum.SECKILL_PRODUCT_LIST.getRealKey(time + ""), seckillId + "");
        if (obj == null) {
            return new SeckillProductVo();
        }

        return JSON.parseObject(obj.toString(), SeckillProductVo.class);
    }


}
